package com.aiden.app.common.view

import android.animation.ObjectAnimator
import android.content.Context
import android.support.v4.widget.NestedScrollView
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup

/**
 * 头部可缩放的NestedScrollView
 *
 * @author yanggeng
 * @date 2019/1/31 上午9:06
 */
class HeadZoomScrollView : NestedScrollView {

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    private var pullY = 0f
    private var zoomViewWidth = 0
    private var zoomViewHeight = 0
    private var isScaling = false

    private var zoomView: View ?= null
    var scaleRatio = 0.4f // 滑动放大系数，系数越大，滑动时放大程度越大
    var maxScaleTimes = 2f // 最大放大倍数
    var replyRatio = 0.5 // 回弹时间系数，系数越小，回弹越快
    private var onScrollListener: OnScrollListener ?= null
    private var downY = 0
    private var downX = 0

    fun setZoomView(zoomView: View) {
        this.zoomView = zoomView
    }

    override fun onFinishInflate() {
        super.onFinishInflate()
        // 不可过度滚动，否则上移后下拉会出现部分空白
        overScrollMode = View.OVER_SCROLL_NEVER
        if (getChildAt(0) != null && getChildAt(0) is ViewGroup && zoomView == null) {
            val child0 = getChildAt(0) as ViewGroup
            if (child0.childCount > 0) {
                zoomView = child0.getChildAt(0)
            }
        }
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {

        when(ev?.action) {
            MotionEvent.ACTION_DOWN -> {
                downY = ev.y.toInt()
                downX = ev.x.toInt()
            }
            MotionEvent.ACTION_MOVE -> {
                val currX = ev.x.toInt()
                val currY = ev.y.toInt()
                if (Math.abs(currY - downY) > Math.abs(currX - downX)) {
                    return true
                }
            }
        }

        return super.onInterceptTouchEvent(ev)
    }

    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        if (zoomViewWidth <= 0 || zoomViewHeight <= 0) {
            zoomViewWidth = zoomView?.measuredWidth!!
            zoomViewHeight = zoomView?.measuredHeight!!
        }
        if (zoomView == null || zoomViewHeight <= 0 || zoomViewWidth <= 0) {
            return super.onTouchEvent(ev)
        }
        when (ev?.action) {
            MotionEvent.ACTION_DOWN -> {
                downY = ev.y.toInt()
            }
            MotionEvent.ACTION_MOVE -> {
                if (!isScaling) {
                    if (scrollY == 0) {
                        pullY = ev.y // 滑动到顶部，纪录位置
                    } else {
                        return super.onTouchEvent(ev)
                    }
                }
                val deltyY = ev.y - downY
                if (deltyY > 0) {
                    if (scrollY > 0) {
                        return super.onTouchEvent(ev)
                    } else {
                        isScaling = true
                        setZoom(deltyY * scaleRatio)
                    }
                } else {
                    if (zoomView?.measuredWidth!! > zoomViewWidth) {
                        isScaling = true
                        setZoom(deltyY * scaleRatio)
                    } else {
                        return super.onTouchEvent(ev)
                    }
                }
                downY = ev.y.toInt()
//                val distance = ((ev.y - pullY) * scaleRatio).toInt()
//                if (distance < 0) return super.onTouchEvent(ev)
//                isScaling = true
//                setZoom(distance.toFloat())
            }
            MotionEvent.ACTION_UP -> {
                isScaling = false
                replyView()
            }
        }
        return super.onTouchEvent(ev)
    }

    override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
        super.onScrollChanged(l, t, oldl, oldt)
        if (onScrollListener != null) onScrollListener?.onScroll(l, t, oldl, oldt)
    }

    fun setOnScrollListener(onScrollListener: OnScrollListener) {
        this.onScrollListener = onScrollListener
    }

    private fun setZoom(s: Float) {
        val tempWidth = zoomView?.measuredWidth!!
        val tempHeight = zoomView?.measuredHeight!!
        val scaleTimes = (tempWidth + s) / (zoomViewWidth * 1.0f)
        // 放大倍数超过最大放大倍数
        if (scaleTimes > maxScaleTimes || scaleTimes <= 1) return

        val layoutParams = zoomView?.layoutParams!!
        layoutParams.width = (tempWidth + s).toInt()
//        layoutParams.height = (tempHeight * scaleTimes).toInt()
        // 设置控件水平居中
//        (layoutParams as MarginLayoutParams).setMargins(-(layoutParams.width - zoomViewWidth) / 2, 0, 0, 0)
        zoomView?.layoutParams = layoutParams
    }

    private fun replyView() {
        val distance = zoomView?.measuredWidth!! - zoomViewWidth

        val anim = ObjectAnimator.ofFloat(0.0f, distance.toFloat()).setDuration((distance * replyRatio).toLong())
        anim.addUpdateListener {
            setZoom(-(it.animatedValue as Float))
        }
        anim.start()
    }

    interface OnScrollListener {
        fun onScroll(scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int)
    }
}